/// ===========================================================================
/// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
/// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
/// PURPOSE.
/// ===========================================================================
/// 
/// Project:        MOSS META Viewer
/// Author:         Leonid Lyublinski 
/// Date:           09/17/2008  Version:        1.0
///
/// ===========================================================================

using System;
using System.Xml;
using System.Collections;
using System.Data;
using System.Runtime.InteropServices;
using System.Security;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AspWebParts = System.Web.UI.WebControls.WebParts;

using MdModel = Microsoft.Office.Server.ApplicationRegistry.MetadataModel;
using Microsoft.Office.Server.ApplicationRegistry.Runtime;
using Microsoft.SharePoint.Portal.WebControls;
using SPWebParts = Microsoft.SharePoint.WebPartPages;
using Microsoft.SharePoint.WebPartPages.Communication;
using Microsoft.SharePoint;

namespace MayaIntl.SharePoint.Portal.WebControls
{
    /// <summary>
    /// Common utilities and shared methods
    /// </summary>
    class Utility
    {
        /// <summary>
        /// Returns list of allowed data types
        /// </summary>
        internal static ArrayList AllowedTypes
        {
            get
            {
                ArrayList at = new ArrayList();
                at.Add("System.Int16");
                at.Add("System.Int32");
                at.Add("System.Int64");
                at.Add("System.UInt16");
                at.Add("System.UInt32");
                at.Add("System.UInt64");
                at.Add("System.Byte");
                at.Add("System.Boolean");
                at.Add("System.String");
                at.Add("System.Char");
                at.Add("System.Decimal");
                //at.Add("System.Double");
                at.Add("System.DateTime");
                at.Add("System.Guid");
                at.Add("System.Single");
                at.Add("System.SByte");
                at.Add("System.TimeSpan");
                return at;
            }
        }

        /// <summary>
        /// Converts Xml string into Datatable
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static DataTable GetTable(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);
            XmlElement v = doc.DocumentElement;
            DataTable table = new DataTable();
            if (v.HasChildNodes) 
            {
                for (int j = 0; j < v.ChildNodes.Count; j++) // Row elements
                {
                    ArrayList values = new ArrayList();
                    XmlNode r = v.ChildNodes[j];
                    if (r.HasChildNodes)
                    {
                        for (int i = 0; i < r.ChildNodes.Count; i++)    // Field elements
                        {
                            XmlNode field = r.ChildNodes[i];
                            string name = (field.Attributes["name"] != null) ? field.Attributes["name"].Value : null;
                            string type = (field.Attributes["type"] != null) ? field.Attributes["type"].Value : null;
                            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(type)) continue;
                            values.Add(field.InnerXml);
                            DataColumn column = new DataColumn(name, Type.GetType(type));
                            table.Columns.Add(column);
                        }
                        DataRow row = table.NewRow();
                        table.Rows.Add(row);
                        // populate values jic
                        for (int i = 0; i < table.Columns.Count; i++)
                        {
                            if (string.IsNullOrEmpty(values[i].ToString()))
                            {
                                row[i] = DBNull.Value;
                            }
                            else
                            {
                                row[i] = Convert.ChangeType(values[i], table.Columns[i].DataType);
                            }
                        }
                    }
                }
            }
            return table;    
        }

        /// <summary>
        /// Serializes BDC View into Xml string
        /// </summary>
        /// <param name="view"></param>
        /// <returns></returns>
        public static string GetXml(MdModel.View view)
        {
            if (view != null && view.Fields.Count > 0)
            {
                XmlDocument doc = new XmlDocument();
                XmlElement v = doc.CreateElement("View");
                doc.AppendChild(v);
                XmlElement r = doc.CreateElement("Row");
                v.AppendChild(r);
                for (int i = 0; i <  view.Fields.Count; i++)
                {
                    MdModel.Field field = view.Fields[i];
                    if (AllowedTypes.Contains(field.TypeDescriptor.TypeName))
                    {
                        XmlElement el = doc.CreateElement("Field");
                        XmlAttribute name = doc.CreateAttribute("name");
                        name.InnerText = field.Name;
                        el.Attributes.Append(name);
                        XmlAttribute type = doc.CreateAttribute("type");
                        type.InnerText = field.TypeDescriptor.TypeName;
                        el.Attributes.Append(type);
                        r.AppendChild(el);
                    }
                }
                return doc.InnerXml;
            }
            else
                return null;
        }

        /// <summary>
        /// Serializes DataTable into Xml string
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public static string GetXml(DataTable table)
        {
            if (table != null && table.Columns.Count > 0)
            {
                ArrayList values = new ArrayList();            
                XmlDocument doc = new XmlDocument();
                XmlElement v = doc.CreateElement("View");
                doc.AppendChild(v);
                for (int j = 0; j < table.Rows.Count; j++)
                {
                    XmlElement r = doc.CreateElement("Row");
                    v.AppendChild(r);
                    DataRow row = table.Rows[j];
                    for (int i = 0; i < table.Columns.Count; i++)
                    {
                        DataColumn column = table.Columns[i];
                        values.Add(row[i]);
                        if (AllowedTypes.Contains(column.DataType.FullName))
                        {
                            XmlElement el = doc.CreateElement("Field");
                            XmlAttribute name = doc.CreateAttribute("name");
                            name.InnerText = column.ColumnName;
                            el.Attributes.Append(name);
                            XmlAttribute type = doc.CreateAttribute("type");
                            type.InnerText = column.DataType.FullName;
                            el.Attributes.Append(type);
                            el.InnerXml = row[i].ToString();
                            r.AppendChild(el);
                        }
                    }
                }
                return doc.InnerXml;
            }
            else
                return null;
        }
        
        /// <summary>
        /// Helper to parse object into string
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string ObjectToString(object o)
        {
            return o.ToString();
        }

        /// <summary>
        /// Helper method to save web part property using SPLimitedWebPartManager
        /// </summary>
        /// <param name="wp"></param>
        /// <param name="scope"></param>
        /// <param name="propertyAssignment"></param>
        public static void SaveProperty(AspWebParts.WebPart wp, AspWebParts.PersonalizationScope scope, EventHandler propertyAssignment)
        {
            using (SPWeb web = new SPSite(HttpContext.Current.Request.Url.AbsoluteUri).OpenWeb())
            {
                using (SPWebParts.SPLimitedWebPartManager wm = web.GetLimitedWebPartManager(HttpContext.Current.Request.Url.AbsoluteUri, scope))
                {
                    AspWebParts.WebPart wpTmp = wm.WebParts[wp.ID];
                    if (wpTmp != null)
                    {
                        web.AllowUnsafeUpdates = true;
                        propertyAssignment(wp, EventArgs.Empty);
                        wm.SaveChanges(wpTmp);
                        web.AllowUnsafeUpdates = false;
                    }
                }
            }
        }
        
    }

    
}
